package com.dhcc.DRGsHosp.facade.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Named;

import org.openkoala.koalacommons.resourceloader.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.dhcc.DRGsHosp.application.OperationAnalysisApplication;
import com.dhcc.DRGsHosp.facade.OperationAnalysisFacade;
import com.dhcc.DRGsHosp.facade.dto.IndexCalDTO;
import com.dhcc.DRGsHosp.facade.impl.assembler.IndexCalAssembler;
import com.dhcc.DRGsHosp.infra.util.DrgsIndex;
/**
 * 
 * 手术分析
 * @ClassName: OperationAnalysisFacadeImpl 
 * @Description ：  
 * @Date: 2017年12月22日 下午10:56:40 
 * @Author ChenHanlin 
 * @Version 2.5.0 DHC-DRGs
 */
@Named("drgsHospFacadeImplOperationAnalysis20171222")
public class OperationAnalysisFacadeImpl implements OperationAnalysisFacade {
	@Autowired
	private OperationAnalysisApplication operationAnalysisApplication;
	@Override
	public List<Map<String,Object>> findOperationLevelAnalysis(IndexCalDTO dto) {
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		StringBuffer sql = new StringBuffer() ;
		sql.append(" select -obj1- , a.totalCaseCnt, \n ") ;
		sql.append(" a.opeCaseCnt, decode(a.totalCaseCnt,0,0,a.opeCaseCnt/a.totalCaseCnt*100) opeCaseCntR, \n ") ;
		sql.append(" a.firlevel, decode(a.opeCaseCnt,0,0,a.firlevel/a.opeCaseCnt*100) firlevelR , \n ") ;
		sql.append(" a.seclevel, decode(a.opeCaseCnt,0,0,a.seclevel/a.opeCaseCnt*100) seclevelR , \n ") ;
		sql.append(" a.thirlevel,decode(a.opeCaseCnt,0,0,a.thirlevel/a.opeCaseCnt*100) thirlevelR , \n ") ;
		sql.append(" a.fourlevel,decode(a.opeCaseCnt,0,0,a.fourlevel/a.opeCaseCnt*100) fourlevelR \n ") ;
		sql.append(" from ( \n ") ;
		sql.append(" select -obj2-  , count(distinct ipinfo.pmainindex) totalCaseCnt , \n ") ;
		sql.append(" sum(case when operation.potype = 'M' and operation.po1400 = 1 then 1 else 0 end) opeCaseCnt, \n ") ;
		sql.append(" sum(case when operation.po0301 = '1' and operation.potype = 'M' and operation.po1400 = 1 then 1 else 0 end) as firlevel, \n ") ;
		sql.append(" sum(case when operation.po0301 = '2' and operation.potype = 'M' and operation.po1400 = 1 then 1 else 0 end) as seclevel, \n ") ;
		sql.append(" sum(case when operation.po0301 = '3' and operation.potype = 'M' and operation.po1400 = 1 then 1 else 0 end) as thirlevel, \n ") ;
		sql.append(" sum(case when operation.po0301 = '4' and operation.potype = 'M' and operation.po1400 = 1 then 1 else 0 end) as fourlevel \n ") ;
		sql.append(" from drgs.mr_baseinfo a \n ");
		sql.append(" left join drgs.mr_ipinfo ipinfo on a.pmainindex = ipinfo.pmainindex \n ");
		sql.append(" left join drgs.mr_operation operation \n ") ;
		sql.append(" on operation.pmainindex = ipinfo.pmainindex \n ") ;
		// 当监测类型是科室时连接科室表
		if("dep".equals(dto.getMonitorType())){
			sql.append(" left join DRGs.t_department dep  \n ") ;
			sql.append(" on ipinfo.p00300001=dep.dep_code  \n ") ;
		}
		sql.append(" where to_char(ipinfo.p00290000,'yyyy-mm-dd') between :dateFrom and :dateTo and 1=1 \n ") ;
		sql.append(" group by  -grbyobj2- \n ") ;
		sql.append(" ) a order by a.ccode \n ") ;
		
		String sqlstr = sql.toString() ;
		if("hosp".equals(dto.getMonitorType())){ 
			sqlstr = sqlstr.replaceAll("-obj1-", " ccode " ) ;
			sqlstr = sqlstr.replaceAll("-obj2-", " 'hosp' as ccode " ) ;
			sqlstr = sqlstr.replaceAll("-grbyobj2-", " 'hosp' " ) ;
		} else if("dep".equals(dto.getMonitorType())){
			sqlstr = sqlstr.replaceAll("-obj1-", " a.ccode ccode,a.ddesc ddesc " ) ;
			sqlstr = sqlstr.replaceAll("-obj2-", " dep.dep_code ccode,dep.dep_name ddesc " ) ;
			sqlstr = sqlstr.replaceAll("-grbyobj2-", " dep.dep_code,dep.dep_name " ) ;
		}
		
		if(StringUtils.hasLength(dto.getPardepCode())) {
			sqlstr = sqlstr.replaceAll("1=1", " dep.dep_code is not null and dep.dep_code = :pardepCode and 1=1 " ) ;
		}
		
		//***医院编码***
		if(StringUtils.hasLength(dto.getHospCode())){
			sqlstr = sqlstr.replaceAll("1=1", " instr('"+dto.getHospCode()+"',a.p00010001)>0 and 1=1 \n " ) ;
		}
		List<Map<String,Object>> listMap = operationAnalysisApplication.executeQueryForList(sqlstr,IndexCalAssembler.toEntity(dto)) ;
		
		return listMap;
	}
	
	@Override
	public List<Map<String, Object>> findDoctorOpeLevelAnalysis(IndexCalDTO dto) {
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		StringBuffer sql = new StringBuffer() ;
		sql.append(" select b.ccode,cg.group_name ddesc, b.depcode,b.depname,b.doctype,b.totalCaseCnt,b.opeCaseCnt, \n ") ;
		sql.append(" decode(b.totalCaseCnt,0,0,b.opeCaseCnt/b.totalCaseCnt*100) opeCaseCntR, \n ") ;
		sql.append(" b.firlevel, decode(b.opeCaseCnt,0,0,b.firlevel/b.opeCaseCnt*100) firlevelR , \n ") ;
		sql.append(" b.seclevel, decode(b.opeCaseCnt,0,0,b.seclevel/b.opeCaseCnt*100) seclevelR , \n ") ;
		sql.append(" b.thirlevel,decode(b.opeCaseCnt,0,0,b.thirlevel/b.opeCaseCnt*100) thirlevelR , \n ") ;
		sql.append(" b.fourlevel,decode(b.opeCaseCnt,0,0,b.fourlevel/b.opeCaseCnt*100) fourlevelR \n ") ;
		sql.append(" from ( \n ") ;
		sql.append(" select a.doccode ccode, a.depcode ,a.depname,a.doctype,count(distinct a.pmainindex) totalCaseCnt , \n ") ;
		sql.append(" sum(case when a.potype = 'M' and a.po1400 = 1 then 1 else 0 end) opeCaseCnt, \n ") ;
		sql.append(" sum(case when a.potype = 'M' and a.po1400 = 1 and a.ope_level = '1' then 1 else 0 end) firlevel, \n ") ;
		sql.append(" sum(case when a.potype = 'M' and a.po1400 = 1 and a.ope_level = '2' then 1 else 0 end) seclevel, \n ") ;
		sql.append(" sum(case when a.potype = 'M' and a.po1400 = 1 and a.ope_level = '3' then 1 else 0 end) thirlevel, \n ") ;
		sql.append(" sum(case when a.potype = 'M' and a.po1400 = 1 and a.ope_level = '4' then 1 else 0 end) fourlevel \n ") ;
		sql.append(" from ( \n ") ;
		sql.append(" select distinct depcode, depname,opr_id ,pmainindex,potype,po1400,ope_level, doc_code doccode,doc_type doctype from ( \n ") ;
		sql.append(" select dep.dep_code depcode ,dep.dep_name depname,operation.id opr_id,operation.pmainindex,operation.potype,operation.po1400 , \n ") ;
		sql.append(" operation.po0301 ope_level,PO0401,PO0501,PO0601 \n ") ;
		sql.append(" from drgs.mr_baseinfo a \n ");
		sql.append(" left join drgs.mr_ipinfo ipinfo on a.pmainindex = ipinfo.pmainindex \n ");
		sql.append(" left join drgs.mr_operation operation \n ") ;
		sql.append(" on operation.pmainindex = ipinfo.pmainindex \n ") ;
		sql.append(" left join DRGs.t_department dep \n ") ;
		sql.append(" on ipinfo.p00300001=dep.dep_code \n ") ;
		sql.append(" where to_char(ipinfo.p00290000,'yyyy-mm-dd') between :dateFrom and :dateTo and 1=1 \n ") ;
//		sql.append(" and dep.dep_code is not null and dep.dep_code = :pardepCode \n ") ;
		sql.append(" )ope unpivot (doc_code for doc_type in (PO0401 as 0,PO0501 as 1,PO0601 as 2)) \n ") ;
		sql.append(" )a group by a.doccode, a.depcode ,a.depname,a.doctype \n ") ;
		sql.append(" )b left join drgs.t_clinicgroup cg on cg.group_code = b.ccode where cg.group_name is not null and cg.group_name<>'无' \n ") ;
		String str = sql.toString() ;
		if(StringUtils.hasLength(dto.getPardepCode())) {
			str = str.replaceAll("1=1", " dep.dep_code is not null and dep.dep_code = :pardepCode and 1=1 " ) ;
		}
		//***医院编码***
		if(StringUtils.hasLength(dto.getHospCode())){
			str = str.replaceAll("1=1", " instr('"+dto.getHospCode()+"',a.p00010001)>0 and 1=1 \n " ) ;
		}
 		List<Map<String,Object>> listMap = operationAnalysisApplication.executeQueryForList(str,IndexCalAssembler.toEntity(dto)) ;
		return listMap ;
	}
	
	@Override
	public Map<String,Object> findOperationCaseDetail(IndexCalDTO dto, int page, int pageSize, int sEcho, int caseTotalCount, String orderColumn, String orderMethod) {
		// 时间格式化
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		StringBuffer sql = new StringBuffer() ;
		sql.append(" select a.pmainindex,dep.dep_code depcode,dep.dep_name depname,a.P00050000 mr_no,a.p00060000 patient_name,dd.dic_desc sex, \n ") ;
		sql.append(" a.p00090000 age_year,to_char(ipinfo.p00250000,'yyyy-mm-dd') in_date,to_char(ipinfo.p00290000,'yyyy-mm-dd') out_date,to_char(ope.po0200 ,'yyyy-mm-dd') ope_date, \n ") ;
		sql.append(" ope.po0101 ope_code, ope.po0100 ope_desc, \n ") ;
		sql.append(" (case when ope.po0301='1' then '一级手术' when ope.po0301='2' then '二级手术' \n ") ;
		sql.append(" when ope.po0301='3' then '三级手术' when ope.po0301='4' then '四级手术' else null end) as oper_level, \n ") ;
		sql.append(" ope.po0400 oper_doctor, \n ") ;
		sql.append(" ope.po0500 assis_one,ope.po0600 assis_two, \n ") ;
		sql.append(" ope.po0800 healgrade_desc , ope.po0801 healgrade_code , \n ") ;
		sql.append(" ope.po0700 anesthesia,ope.po0900 anesthetist \n ") ;
		sql.append(" from drgs.mr_baseinfo a \n ");
		sql.append(" left join drgs.mr_ipinfo ipinfo on a.pmainindex = ipinfo.pmainindex \n ");
		sql.append(" left join drgs.mr_operation ope on ope.pmainindex = a.pmainindex \n ") ;
		sql.append(" left join drgs.t_department dep on dep.dep_code = ipinfo.p00300001 \n ") ;
		sql.append(" left join drgs.mr_dictionarydata dd on dd.dic_code = 'P00070001' and dd.dic_value = a.p00070001 \n ") ;
		sql.append(" where to_char(ipinfo.p00290000,'yyyy-mm-dd') between :dateFrom and :dateTo and 1=1 and ope.potype = 'M' and ope.po1400 = 1 \n ") ;
		String str = sql.toString() ;
		
		// 科室条件
		if("null".equals(dto.getPardepCode())) {
			str = str.replaceAll("1=1", " dep.dep_code is null \n and 1=1 " ) ;
		} else if(StringUtils.hasLength(dto.getPardepCode())) {
			str = str.replaceAll("1=1", " dep.dep_code is not null and dep.dep_code = :pardepCode \n and 1=1 " ) ;
		}
		
		// 医师条件
		if(StringUtils.hasLength(dto.getDoctorCode())) {
			str = str.replaceAll("1=1", " (ope.po0401 = :doctorCode or ope.po0501 = :doctorCode or ope.po0601 = :doctorCode ) \n and 1=1 " ) ;
		}
		// 手术级别条件
		String opeLevels = dto.getOpeLevel() ;
		if(StringUtils.hasLength(opeLevels)) {
			String[] opeLevelsa = opeLevels.split(",") ;
			String condition = "" ;
			for(String s : opeLevelsa) {
				condition += " ope.po0301 = '"+s+"' or " ;
			}
			condition = condition.substring(0,condition.lastIndexOf("or")) ;
			str = str.replaceAll("1=1", " ("+condition+") \n and 1=1 " ) ;
		}
		// 搜索条件
		if(StringUtils.hasLength(dto.getType2())) {
			str = str.replaceAll("1=1", " (instr(dep.dep_name,:type2)>0  or instr(a.P00050000,:type2)>0 or instr(a.p00060000,:type2)>0 or instr(ope.po0100,:type2)>0) \n and 1=1 " ) ;
		}
		
		//***医院编码***
		if(StringUtils.hasLength(dto.getHospCode())){
			str = str.replaceAll("1=1", " instr('"+dto.getHospCode()+"',a.p00010001)>0 and 1=1 " ) ;
		}
		dto.setSqlStr(str);
		//总数为0 或者 查询条件不为空 则重新获取病例总数
        if (caseTotalCount == 0 || StringUtils.hasLength(dto.getType2())) {
            caseTotalCount = operationAnalysisApplication.findCaseCount(IndexCalAssembler.toEntity(dto));
        }
        
        //查询病例集合
        List<Map<String, Object>> caseMaps = operationAnalysisApplication.findCaseList(IndexCalAssembler.toEntity(dto),page,pageSize,orderColumn,orderMethod);
        
        Map<String,Object> caseListResultMaps = new HashMap<String, Object>();
	    caseListResultMaps.put("sEcho",sEcho);	 
		caseListResultMaps.put("iTotalRecords", caseTotalCount);
        caseListResultMaps.put("iTotalDisplayRecords", caseTotalCount);
        caseListResultMaps.put("caseList", caseMaps);  
		return caseListResultMaps ;
	}
	
	@Override
	public List<Map<String, Object>> findOperationInfoByLevel(IndexCalDTO dto, String level) {
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		StringBuffer sql = new StringBuffer() ;
		sql.append(" select distinct dense_rank() over (order by a.opeCode desc) rk, a.*,a.cntindep/cntOpe*100 as cntindepR from ( \n ") ;
		sql.append(" select ope.po0101 opeCode,ope.po0100 opeDesc,(case when ope.po0301='1' then '一级' when ope.po0301='2' then '二级' \n ") ;
		sql.append(" when ope.po0301='3' then '三级' when ope.po0301='4' then '四级' else null end) as oper_level , \n ") ;
		sql.append(" count(ipinfo.pmainindex) over (partition by ope.po0101 order by ope.po0101) cntOpe , \n ") ;
		sql.append(" dep.dep_code,dep.dep_name,count(ipinfo.pmainindex) over (partition by ope.po0101,dep.dep_code) cntindep \n ") ;
		sql.append(" from drgs.mr_baseinfo a \n ") ;
		sql.append(" left join drgs.mr_ipinfo ipinfo on ipinfo.pmainindex = a.pmainindex \n ") ;
		sql.append(" left join drgs.mr_operation ope on ope.pmainindex = a.pmainindex \n ") ;
		sql.append(" left join drgs.t_department dep on dep.dep_code = ipinfo.p00300001 \n ") ;
		sql.append(" left join drgs.mr_dictionarydata dd on dd.dic_code = 'P00070001' and dd.dic_value = a.p00070001 \n ") ;
		sql.append(" where to_char(ipinfo.p00290000,'yyyy-mm-dd') between :dateFrom and :dateTo and 1=1 and ope.potype = 'M' and ope.po1400 = 1 \n ") ;
		sql.append(" and dep.dep_code is not null and ope.po0301 = '"+level+"' \n ") ;
		sql.append(" )a \n ") ;
		String str = sql.toString() ;
		if(StringUtils.hasLength(dto.getPardepCode())) {
			str = str.replaceAll("1=1", " dep.dep_code is not null and dep.dep_code = :pardepCode and 1=1 \n " ) ;
		}
		
		//***医院编码***
		if(StringUtils.hasLength(dto.getHospCode())){
			str = str.replaceAll("1=1", " instr('"+dto.getHospCode()+"',a.p00010001)>0 and 1=1 \n " ) ;
		}
		
		List<Map<String,Object>> listMap = operationAnalysisApplication.executeQueryForList(str,IndexCalAssembler.toEntity(dto)) ;
		return listMap ;
	}
}
